import GraphVertex from '../res/data-structures/graph/GraphVertex.js';
import GraphEdge from '../res/data-structures/graph/GraphEdge.js';
import Graph from '../res/data-structures/graph/Graph.js';
import prime from '../res/graph/prim/prim.js';
import kruskal from '../res/graph/kruskal/kruskal.js';
import Boruvka from './Boruvka.js'
import detectUndirectedCycle from '../res/graph/detect-cycle/detectUndirectedCycle.js';
//样图数据
let exampleGraph=[
    {
       "nodeNum":9,
       "nodeLocation":[
           {
               x:50,y:50
           },
           {
               x:0,y:0
           },
           {
               x:40,y:25
           },
           {
               x:20,y:25
           },
           {
               x:50,y:0
           },
           {
               x:0,y:50
           },
           {
               x:40,y:85
           },
           {
               x:70,y:50
           },
           {
               x:100,y:50
           }
       ],
       "edgeList":[
            {
                "source":0,
                "target":5,
                "value":8
            },
            {
                "source":0,
                "target":2,
                "value":2
            },
            {
                "source":0,
                "target":7,
                "value":2
            },
            {
                "source":0,
                "target":4,
                "value":3
            },
            {
                "source":1,
                "target":5,
                "value":9
            },
            {
                "source":1,
                "target":4,
                "value":13
            },
            {
                "source":4,
                "target":7,
                "value":4
            },
            {
                "source":4,
                "target":8,
                "value":5
            },
            {
                "source":3,
                "target":5,
                "value":5
            },
            {
                "source":3,
                "target":2,
                "value":4
            },
            {
                "source":5,
                "target":6,
                "value":5
            },
            {
                "source":6,
                "target":7,
                "value":9
            },
            {
                "source":6,
                "target":8,
                "value":10
            },
            {
                "source":7,
                "target":8,
                "value":5
            }
        ] 
    },
    {
       "nodeNum":9,
       "nodeLocation":[
           {
               x:0,y:50
           },
           {
               x:40,y:15
           },
           {
               x:80,y:15
           },
           {
               x:120,y:15
           },
           {
               x:160,y:50
           },
           {
               x:120,y:85
           },
           {
               x:80,y:85
           },
           {
               x:40,y:85
           },
           {
               x:80,y:50
           }
       ],
       "edgeList":[
            {
                "source":0,
                "target":1,
                "value":4
            },
            {
                "source":0,
                "target":7,
                "value":8
            },
            {
                "source":1,
                "target":7,
                "value":11
            },
            {
                "source":1,
                "target":2,
                "value":8
            },
            {
                "source":7,
                "target":8,
                "value":7
            },
            {
                "source":6,
                "target":7,
                "value":1
            },
            {
                "source":2,
                "target":8,
                "value":2
            },
            {
                "source":6,
                "target":8,
                "value":6
            },
            {
                "source":5,
                "target":6,
                "value":2
            },
            {
                "source":2,
                "target":5,
                "value":4
            },
            {
                "source":2,
                "target":3,
                "value":7
            },
            {
                "source":3,
                "target":5,
                "value":14
            },
            {
                "source":3,
                "target":4,
                "value":9
            },
            {
                "source":4,
                "target":5,
                "value":10
            }
        ] 
    },
    {
       "nodeNum":7,
       "nodeLocation":[
           {
               x:10,y:10
           },
           {
               x:50,y:25
           },
           {
               x:90,y:10
           },
           {
               x:10,y:50
           },
           {
               x:80,y:50
           },
           {
               x:50,y:75
           },
           {
               x:90,y:75
           }
       ],
       "edgeList":[
            {
                "source":0,
                "target":1,
                "value":7
            },
            {
                "source":0,
                "target":3,
                "value":4
            },
            {
                "source":1,
                "target":3,
                "value":9
            },
            {
                "source":1,
                "target":2,
                "value":11
            },
            {
                "source":1,
                "target":4,
                "value":10
            },
            {
                "source":2,
                "target":4,
                "value":5
            },
            {
                "source":3,
                "target":4,
                "value":15
            },
            {
                "source":3,
                "target":5,
                "value":6
            },
            {
                "source":4,
                "target":5,
                "value":12
            },
            {
                "source":4,
                "target":6,
                "value":8
            },
            {
                "source":5,
                "target":6,
                "value":13
            }
        ] 
    },
    {
       "nodeNum":8,
       "nodeLocation":[
            {x:10,y:50},{x:30,y:30},{x:30,y:70},{x:60,y:50},{x:70,y:-10},{x:95,y:35},{x:95,y:65},{x:70,y:110}
       ],
       "edgeList":[
            {
                "source":0,
                "target":1,
                "value":4
            },
            {
                "source":0,
                "target":2,
                "value":3
            },
            {
                "source":1,
                "target":2,
                "value":5
            },
            {
                "source":1,
                "target":4,
                "value":9
            },
            {
                "source":1,
                "target":3,
                "value":5
            },
            {
                "source":2,
                "target":3,
                "value":5
            },
            {
                "source":2,
                "target":7,
                "value":5
            },
            {
                "source":3,
                "target":4,
                "value":7
            },
            {
                "source":3,
                "target":5,
                "value":6
            },
            {
                "source":3,
                "target":6,
                "value":5
            },
            {
                "source":3,
                "target":7,
                "value":4
            },
            {
                "source":4,
                "target":5,
                "value":3
            },
            {
                "source":5,
                "target":6,
                "value":2
            },
            {
                "source":6,
                "target":7,
                "value":6
            }
        ]  
    },
    {
       "nodeNum":6,
       "nodeLocation":[
            {x:50,y:0},{x:100,y:40},{x:85,y:100},{x:15,y:100},{x:0,y:40},{x:50,y:50}
       ],
       "edgeList":[
            {
                "source":0,
                "target":1,
                "value":14
            },
            {
                "source":0,
                "target":4,
                "value":22
            },
            {
                "source":0,
                "target":5,
                "value":13
            },
            {
                "source":1,
                "target":2,
                "value":21
            },
            {
                "source":1,
                "target":5,
                "value":12
            },
            {
                "source":2,
                "target":5,
                "value":18
            },
            {
                "source":2,
                "target":3,
                "value":16
            },
            {
                "source":3,
                "target":4,
                "value":20
            },
            {
                "source":3,
                "target":5,
                "value":19
            },
            {
                "source":4,
                "target":5,
                "value":24
            },

       ]
    },
    {
       "nodeNum":11,
       "nodeLocation":[
            {x:0,y:50},{x:25,y:20},{x:50,y:20},{x:75,y:20},{x:75,y:50},{x:50,y:50},
            {x:25,y:50},{x:25,y:80},{x:50,y:80},{x:75,y:80},{x:100,y:50}
       ],
       "edgeList":[
            {
                "source":0,
                "target":1,
                "value":8
            },
            {
                "source":0,
                "target":7,
                "value":8
            },
            {
                "source":0,
                "target":6,
                "value":7
            },
            {
                "source":1,
                "target":2,
                "value":3
            },
            {
                "source":2,
                "target":3,
                "value":5
            },
            {
                "source":2,
                "target":6,
                "value":5
            },
            {
                "source":2,
                "target":4,
                "value":6
            },
            {
                "source":3,
                "target":4,
                "value":1
            },
            {
                "source":3,
                "target":10,
                "value":12
            },
            {
                "source":4,
                "target":10,
                "value":10
            },
            {
                "source":4,
                "target":5,
                "value":2
            },
            {
                "source":4,
                "target":8,
                "value":7
            },
            {
                "source":5,
                "target":6,
                "value":9
            },
            {
                "source":5,
                "target":8,
                "value":3
            },
            {
                "source":7,
                "target":8,
                "value":9
            },
            {
                "source":8,
                "target":9,
                "value":2
            },
            {
                "source":9,
                "target":10,
                "value":2
            }
       ]
    },
    {
       "nodeNum":8,
       "nodeLocation":[
            {x:0,y:50},{x:20,y:25},{x:20,y:75},{x:50,y:50},
            {x:80,y:15},{x:120,y:30},{x:120,y:70},{x:80,y:85}
       ],
       "edgeList":[
            {
                "source":0,
                "target":1,
                "value":4
            },
            {
                "source":0,
                "target":2,
                "value":3
            },
            {
                "source":1,
                "target":2,
                "value":5
            },
            {
                "source":1,
                "target":3,
                "value":5
            },
            {
                "source":1,
                "target":4,
                "value":9
            },
            {
                "source":2,
                "target":3,
                "value":5
            },
            {
                "source":2,
                "target":7,
                "value":5
            },
            {
                "source":3,
                "target":4,
                "value":7
            },
            {
                "source":3,
                "target":5,
                "value":6
            },
            {
                "source":3,
                "target":6,
                "value":5
            },
            {
                "source":3,
                "target":7,
                "value":4
            },
            {
                "source":4,
                "target":5,
                "value":3
            },
            {
                "source":5,
                "target":6,
                "value":2
            },
            {
                "source":6,
                "target":7,
                "value":6
            },
       ]  
    },
    {
       "nodeNum":8,
       "nodeLocation":[
            {x:50,y:0},{x:0,y:25},{x:0,y:75},{x:50,y:50},
            {x:100,y:25},{x:50,y:100},{x:100,y:75},{x:150,y:50}
       ],
       "edgeList":[
            {
                "source":0,
                "target":1,
                "value":6
            },
            {
                "source":0,
                "target":4,
                "value":6
            },
            {
                "source":0,
                "target":3,
                "value":4
            },
            {
                "source":1,
                "target":2,
                "value":2
            },
            {
                "source":1,
                "target":3,
                "value":5
            },
            {
                "source":2,
                "target":3,
                "value":6
            },
            {
                "source":2,
                "target":5,
                "value":4
            },
            {
                "source":3,
                "target":4,
                "value":8
            },
            {
                "source":3,
                "target":5,
                "value":9
            },
            {
                "source":3,
                "target":6,
                "value":7
            },
            {
                "source":4,
                "target":6,
                "value":2
            },
            {
                "source":4,
                "target":7,
                "value":3
            },
            {
                "source":5,
                "target":6,
                "value":5
            },
            {
                "source":6,
                "target":7,
                "value":7
            }
       ]  
    }
];
function getOption(graphInfo){
//给节点设置样式
    let nodes=graphInfo['nodes'];
    let links=graphInfo['links'];
    //console.log(links);
//设置option样式
    return {
        title: {
            text: title,
            left: 'center',
            textStyle:{
                fontSize:20
            },
            bottom:0
        },
        tooltip: {
            trigger: 'item'
        },
        backgroundColor:'white',
        roam: true,
        series: [
            {
                type: 'graph',
                layout: 'none',
                symbol: "circle",
                edgeSymbol:['none', 'none'],
                symbolSize: 27,
                edgeSymbolSize: 10,
                nodes: nodes,
                links: links,
                label: {
                    normal: {
                        show: true
                    }
                },
                draggable:true
            }
        ]
    };
}
function nodeStyle(title,x,y){
   return  { 
       name: title,
       x:x,y:y,
       itemStyle: {borderColor: 'black',color:'white',borderWidth: 3},
       label:{show:true,position:"inside",fontSize:15,color:'black',fontWeight:'bold'}}
}
function edgeStyle(selectNode,value){
    return {
        source: selectNode[0],
        target: selectNode[1],
        value:value,
        lineStyle: {
            width: 5,
            color: '#000',
            type:'solid',
            opacity:0.8,
            ignoreForceLayout:true
        },
        label:{
             show:true,
             formatter:'{c}',
             fontSize:15
        }
    };
}
//获取节点
function getNodes(Num,nodeLocation){
    let nodes=[];
    console.log(nodeLocation[0].x);
    let nodeTitle=['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']
    for(let i=0;i< Num;i++){
        let str="";
        for(let j=0;j<=parseInt(i/26);j++){
            str+=nodeTitle[i-parseInt(i/26)*26];
        }
        nodes.push(nodeStyle(str,nodeLocation[i].x,nodeLocation[i].y))
    }
    return nodes;
}
//导入边
function getLoadLinks(){
   let links1=[];
   let edgeList=graphItem.edgeList;
   let len=edgeList.length;
   for(let i=0;i<len;i++){
      links1.push(edgeStyle([edgeList[i].source,edgeList[i].target],edgeList[i].value))
   }
   return links1;
}
//初始化数据
function initData(){
    graphItem=[]; //显示的样图数据
    nodes=[],links=[],option={},title="";
    showEdgeIndex=0;
    edgeTreeList=[];
    subLineIndex=-1;
    showCircle1=false;
    selectNodeIndex=-1;
}
//由字母获取 下标  eulerianPathSet转 每一条边 逐步显示
function getIndex(letter){
  let nodeTitle=['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'];
  let len=letter.length;
  let l=letter[0];
  let index=getArrayIndex(nodeTitle,l);
  return index+26*(len-1);
}
function getArrayIndex(arr, obj) {
    var i = arr.length;
    while (i--) {
        if (arr[i] === obj) {
            return i;
        }
    }
    return -1;
}
//显示红色
function showLinksRed(index1,index2){
    let index=0;
    for(let i=0;i<links.length;i++){
        if((links[i].source==index1&&links[i].target==index2)||(links[i].source==index2&&links[i].target==index1))
        {
            index=i;
            break;
        }
    }
    option.series[0].links[index].lineStyle.color="red";
    option.series[0].links[index].lineStyle.width=10;
    myChart.setOption(option);
}
function showLinksRed1(index1,index2){
    let index=0;
    for(let i=0;i<links.length;i++){
        if((links[i].source==index1&&links[i].target==index2)||(links[i].source==index2&&links[i].target==index1))
        {
            index=i;
            break;
        }
    }
    option.series[0].links[index].lineStyle.color="red";
    option.series[0].links[index].lineStyle.width=10;
    let value=option.series[0].links[index].value;
    return {value,index};
}
//prime算法
function showPrime(){
    if(selectNodeIndex==-1){
        modalApp.modalAlert('未选择起点');
        return;
    }
   //Prime算法
    title="Prime算法";
    let vertexList=[];
    const graph = new Graph();
    let edgeTreeList1={};
    for(let i=0;i<nodes.length;i++){
        let obj=new GraphVertex(nodes[i].name);
        vertexList.push(obj);
        graph.addVertex(obj);
    }
    for(let j=0;j<links.length;j++){
        graph.addEdge(new GraphEdge(vertexList[links[j].source], vertexList[links[j].target],links[j].value))
    }
    console.log(graph.getAllVertices());
    try{
        edgeTreeList1 = prime(graph,selectNodeIndex).edges;
        showEdgeIndex=0;
    }catch(e){
        console.log(e);
    }
    console.log(edgeTreeList1);
    //先要对 所选的边的权值进行从小到大排序 然后再进行下一步的显示
    for(let o in edgeTreeList1){
        edgeTreeList.push(edgeTreeList1[o]);
    }
    console.log(edgeTreeList);
    option.title.text=title;
    myChart.setOption(option);
    modalApp.modalAlert('运行成功,请点击下一步逐步显示');
    nextEdges();

}
//Kruskal算法
function showKruskal(){
    title="Kruskal算法";
    let vertexList=[];
    const graph = new Graph();
    let edgeTreeList1={};
    for(let i=0;i<nodes.length;i++){
        let obj=new GraphVertex(nodes[i].name);
        vertexList.push(obj);
        graph.addVertex(obj);
    }
    for(let j=0;j<links.length;j++){
        graph.addEdge(new GraphEdge(vertexList[links[j].source], vertexList[links[j].target],links[j].value))
    }
    console.log(graph);
    try{
        edgeTreeList1 = kruskal(graph).edges;
        showEdgeIndex=0;
    }catch(e){
        console.log(e);
    }
    console.log(edgeTreeList1);
    //先要对 所选的边的权值进行从小到大排序 然后再进行下一步的显示
    for(let o in edgeTreeList1){
        edgeTreeList.push(edgeTreeList1[o]);
    }
    console.log(edgeTreeList);
    option.title.text=title;
    myChart.setOption(option);
    modalApp.modalAlert('运行成功,请点击下一步逐步显示');
    nextEdges();
}
//破圈法
function showBreakCircle(){
    title="破圈法";
    let vertexList=[];
    const graph = new Graph();
    let edgeTreeList1={};
    for(let i=0;i<nodes.length;i++){
        let obj=new GraphVertex(nodes[i].name);
        vertexList.push(obj);
        graph.addVertex(obj);
    }
    for(let j=0;j<links.length;j++){
        graph.addEdge(new GraphEdge(vertexList[links[j].source], vertexList[links[j].target],links[j].value))
    }
    edgeTreeList1=detectUndirectedCycle(graph);
    let obj,weight=0;
    if(edgeTreeList1==null){
        modalApp.modalAlert('显示完毕');
        
        showCircle1=-1;
        for(let i=0;i<links.length;i++){
            links[i].lineStyle.color='black';
            links[i].lineStyle.width=5;
        }
        myChart.setOption(option);
        return;
    }
    for(let o in edgeTreeList1){
        obj= showLinksRed1(getIndex(o),getIndex(edgeTreeList1[o].value));
        if(obj.value>weight){
            weight=obj.value;
            subLineIndex=obj.index;
        }
    }
    myChart.setOption(option);
}
//Boruvka法
function showBoruvka(){
    title="Boruvka算法";
    let vertexList=[];
    const graph = new Graph();
    edgeTreeList=[];
    let graphList=[];
    for(let i=0;i<nodes.length;i++){
        let GraphVertex1=new GraphVertex(nodes[i].name);
        graphList.push(new Graph().addVertex(GraphVertex1));
        let obj=new GraphVertex(nodes[i].name);
        vertexList.push(obj);
        graph.addVertex(obj);
    }
    for(let j=0;j<links.length;j++){
        edgeTreeList.push(new GraphEdge(vertexList[links[j].source], vertexList[links[j].target],links[j].value))
    }
    console.log(graphList);
    console.log(edgeTreeList);
    try{
        edgeTreeList= Boruvka(graphList,edgeTreeList);
        showEdgeIndex=0;
    }catch(e){
        console.log(e);
    }
    console.log(edgeTreeList);
    option.title.text=title;
    myChart.setOption(option);
    modalApp.modalAlert('运行成功,请点击下一步逐步显示');
    nextEdges();
}
//逐步显示过程
function nextEdges(){
    if(showEdgeIndex<edgeTreeList.length){
        let index1=getIndex(edgeTreeList[showEdgeIndex].startVertex.value);
        let index2=getIndex(edgeTreeList[showEdgeIndex].endVertex.value);
        showLinksRed(index1,index2);
        showEdgeIndex++;
    }
    else{
        modalApp.modalAlert('显示完毕');
    }    
}

//破圈法减边
function subLineDeatil(){
    option.series[0].links.splice(subLineIndex,1);
    myChart.setOption(option);
}
//显示回路
function showCircle(){
    for(let i=0;i<links.length;i++){
        links[i].lineStyle.color='black';
        links[i].lineStyle.width=5;
    }
    let vertexList=[];
    const graph = new Graph();
    let edgeTreeList1={};
    for(let i=0;i<nodes.length;i++){
        vertexList.push(new GraphVertex(nodes[i].name))
    }
    for(let j=0;j<links.length;j++){
        graph.addEdge(new GraphEdge(vertexList[links[j].source], vertexList[links[j].target],links[j].value))
    }
    edgeTreeList1=detectUndirectedCycle(graph);
    let obj,weight=0;
    if(edgeTreeList1==null){
        for(let i=0;i<links.length;i++){
            links[i].lineStyle.color='black';
            links[i].lineStyle.width=5;
        }
        modalApp.modalAlert('显示完毕');
        showCircle1=-1;
        myChart.setOption(option);
        return;
    }
    for(let o in edgeTreeList1){
        obj= showLinksRed1(getIndex(o),getIndex(edgeTreeList1[o].value));
        if(obj.value>weight){
            weight=obj.value;
            subLineIndex=obj.index;
        }
    }
    myChart.setOption(option);
}

let myChart = echarts.init(document.getElementById('echartsDiv'));
let graphItem=[]; //显示的样图数据
let nodes=[],links=[],option={},title="";  //显示图的点集和边集
let showEdgeIndex=0;  //逐步显示边的下标
let subLineIndex=-1;  //破圈法 减最大权值边的算法
let showCircle1=false;  //破圈法 显示回路还是减边
let edgeTreeList=[]; //算法计算得到的生成树的边的顺序
let selectNodeIndex=-1; //prime算法选择起点
var app=new Vue({
    el: '#app',
    data: {
      algorithmSelect:"选择算法",
      exampleGraph:[
          {
              name:"样图1",
              imgUrl:"res/image/1.png"
          },
          {
              name:"样图2",
              imgUrl:"res/image/2.png"
          },
          {
              name:"样图3",
              imgUrl:"res/image/3.png"
          },
          {
              name:"样图4",
              imgUrl:"res/image/4.png"
          },
           {
              name:"样图5",
              imgUrl:"res/image/5.png"
          },
          {
              name:"样图6",
              imgUrl:"res/image/6.png"
          },
          {
              name:"样图7",
              imgUrl:"res/image/7.png"
          },
          {
              name:"样图8",
              imgUrl:"res/image/8.png"
          }
      ]
    },
    methods:{
        selectMenu:function(message){
            console.log(message);
            this.algorithmSelect=message;
        },
        showGraph(index){
            initData();
            console.log(index);
            graphItem=exampleGraph[index];
            nodes=getNodes(graphItem.nodeNum,graphItem.nodeLocation);
            links=getLoadLinks();
            let jsonData={"nodes":nodes,"links":links}
            option=getOption(jsonData);
            myChart.setOption(option);
        },
        algorithmRun(){
            this.resetProcess();
            if(graphItem.length==0){
                modalApp.modalAlert('未选择算法');
                return;
            }
            if(this.algorithmSelect=="选择算法"){
                modalApp.modalAlert('未选择算法');
                return;
            }
            //显示过程
            if(this.algorithmSelect=="Prime算法") showPrime();
            if(this.algorithmSelect=="Kruskal算法") showKruskal();
            if(this.algorithmSelect=="破圈法") showBreakCircle();
            if(this.algorithmSelect=="Boruvka算法") showBoruvka();
        },
        showNext(){
            //破圈法单独处理 
           if(this.algorithmSelect!="破圈法")
           nextEdges();
           else{
                console.log(showCircle1);
               //破圈法 先显示 回路 然后除去回路中权值最大的边
               if(showCircle1==true){
                   showCircle();
                   showCircle1=false;
               }
               else if(showCircle1==false){
                   subLineDeatil();
                   showCircle1=true;
               }
               else{
                   modalApp.modalAlert('显示完毕');
               }
           }
        },
        resetProcess(){
            //重置显示
            for(let i=0;i<links.length;i++){
                    links[i].lineStyle.color='black';
                    links[i].lineStyle.width=5;
            }
            showEdgeIndex=0;
            edgeTreeList=[];
            subLineIndex=-1;
            myChart.setOption(option);
        }
    }
})
var modalApp=new Vue({
    el:"#myModal1",
    data:{
        message:""
    },
    methods:{
        modalAlert(str){
            this.message=str;
            $('#myModal1').modal('toggle');
        }
    }
})
myChart.on('click', function (params) {
    console.log(params);
    if(params.dataType=='node'){
        if(selectNodeIndex==-1){
            selectNodeIndex=params.dataIndex;
            option.series[0].nodes[params.dataIndex].itemStyle.color="#007bff";
            option.series[0].nodes[params.dataIndex].itemStyle.borderColor="white";
            option.series[0].nodes[params.dataIndex].label.color='white';
        }
        else{
           if(selectNodeIndex==params.dataIndex){
               selectNodeIndex=-1;
               option.series[0].nodes[params.dataIndex].itemStyle.color="white";
               option.series[0].nodes[params.dataIndex].itemStyle.borderColor="black";
               option.series[0].nodes[params.dataIndex].label.color='black';
            }
           else{
               option.series[0].nodes[selectNodeIndex].itemStyle.color="white";
               option.series[0].nodes[selectNodeIndex].itemStyle.borderColor="black";
               option.series[0].nodes[selectNodeIndex].label.color='black';
               option.series[0].nodes[params.dataIndex].itemStyle.color="#007bff";
               option.series[0].nodes[params.dataIndex].itemStyle.borderColor="white";
               option.series[0].nodes[params.dataIndex].label.color='white';
               selectNodeIndex=params.dataIndex;

           }
        }
        console.log(selectNodeIndex);
        myChart.setOption(option);
    }         
});